#include "WinUnit.h"
#include "HandHistoryParser.h"
//#include "HandInfo.h"
//#include "HandInfoExtractor.h"
//#include "FileNamesRetriever.h"
#include "Player.h"
#include "Action.h"
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include <functional>
#include <direct.h>

using namespace std;
//using namespace tr1;

namespace
{
	HandHistoryParser parser = HandHistoryParser();
	char workingDir[_MAX_PATH];
	string WORKING_DIR;
	string SAMPLES_DIR;
	string PROJECT_DIR;	
}

FIXTURE(MyFixture);

SETUP(MyFixture)
{
	_getcwd(workingDir, _MAX_PATH);
	WORKING_DIR = string(workingDir);
	SAMPLES_DIR = WORKING_DIR + "\\..\\..\\..\\data\\samples\\";
	PROJECT_DIR = WORKING_DIR + "\\..\\Pokernut.Parsing.Tests\\";
}

TEARDOWN(MyFixture)
{
	// clean up after yourself here!
}

struct PlayerName: public binary_function<Player, string, bool> {
	bool operator () ( const Player & player, const string & name) const {
		return player.Name() == name;
	}
};

struct ActionPlayerName: public binary_function<Action, string, bool> {
	bool operator () ( const Action & action, const string & name) const {
		return action.PlayerName() == name;
	}
};
struct ActionSpecific: public binary_function<Action, Action, bool> {
	bool operator () ( const Action & action, const Action & actionSpecific) const {
		return action.PlayerName() == actionSpecific.PlayerName() &&
			action.ActionType() == actionSpecific.ActionType() &&
			action.Amount() == actionSpecific.Amount();
	}
};

bool IsPlayerNameCaptured(string nameToTest, string dirName, string fileName)
{
	string NAME_TO_TEST = nameToTest;
	list<Hand> & hands = parser.Parse(dirName + fileName);
	
	list<Hand>::iterator handsIt = hands.begin();

	list<Player> & players = handsIt->Players();
	list<Player>::iterator playersIt;

	bool foundName = false;
	playersIt = find_if(players.begin(), players.end(), bind2nd(PlayerName(), NAME_TO_TEST));
	if (playersIt != players.end())
	{
		foundName = true;
	}

	list<Action> & actions = handsIt->Actions();
	list<Action>::iterator actionsIt;

	bool foundAction = false;
	actionsIt = find_if(actions.begin(), actions.end(), bind2nd(ActionPlayerName(), NAME_TO_TEST));
	if (actionsIt != actions.end())
	{
		foundAction = true;
	}

	return foundName && foundAction;
}

bool IsActionCaptured(Action actionToTest, string dirName, string fileName)
{
	list<Hand> & hands = parser.Parse(dirName + fileName);
	
	list<Hand>::iterator handsIt = hands.begin();

	list<Action> & actions = handsIt->Actions();
	list<Action>::iterator actionsIt;

	bool foundAction = false;
	actionsIt = find_if(actions.begin(), actions.end(), bind2nd(ActionSpecific(), actionToTest));
	if (actionsIt != actions.end())
	{
		foundAction = true;
	}

	return foundAction;
}

bool AreBlindsCorrect(float sb, float bb, string dirName, string fileName)
{
	list<Hand> & hands = parser.Parse(dirName + fileName);

	list<Hand>::iterator handsIt = hands.begin();

	float sb_ = handsIt->Sb();
	float  bb_ = handsIt->Bb();

	return sb_ == sb && bb_ == bb;
}

BEGIN_TESTF(SpecialNamesTest, MyFixture)
{
	
	WIN_ASSERT_TRUE(
	IsPlayerNameCaptured("J.WILMANN", PROJECT_DIR, "PeriodInNameHandText.txt") &&
	IsPlayerNameCaptured("Kete 1955", PROJECT_DIR, "SpaceInNameHandText.txt")	
	);
}
END_TESTF

BEGIN_TESTF(SpecialActionsTest, MyFixture)
{
	Action MixmastrBets10("mixmastr", BET, 10);
	WIN_ASSERT_TRUE(
	IsActionCaptured(MixmastrBets10, SAMPLES_DIR, "singlehand.txt")
	);
}
END_TESTF

BEGIN_TESTF(BlindsLessThanOneTest, MyFixture)
{		
	WIN_ASSERT_TRUE(
	AreBlindsCorrect(0.5, 1, PROJECT_DIR, "BlindsLessThanOneDollarText.txt")
	);
}
END_TESTF